package com.css.zfzx.fxpg.modules.popgdp.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.css.bpm.platform.utils.PlatformObjectUtils;
import com.css.bpm.platform.utils.PlatformPageUtils;
import com.css.zfzx.fxpg.common.utils.VectorDataUtil;
import com.css.zfzx.fxpg.modules.buildings.data.repository.entity.FxBuildingsEntity;
import com.css.zfzx.fxpg.modules.popgdp.repository.FxPopGDPDataImport;
import com.css.zfzx.fxpg.modules.popgdp.repository.FxPopGDPNativeRepository;
import com.css.zfzx.fxpg.modules.popgdp.repository.FxPopGDPRepository;
import com.css.zfzx.fxpg.modules.popgdp.repository.entity.FxPopGDPEntity;
import com.css.zfzx.fxpg.modules.popgdp.service.FxPopGDPService;
import com.css.zfzx.fxpg.modules.popgdp.viewobjects.FxPopGDPQueryParams;
import com.css.zfzx.fxpg.modules.popgdp.viewobjects.FxPopGDPVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author andy
 * @date 2020-11-11
 */
@Service
public class FxPopGDPServiceImpl implements FxPopGDPService {

    @Autowired
    private FxPopGDPRepository fxPopGDPRepository;

    @Autowired
    private FxPopGDPNativeRepository fxPopGDPNativeRepository;

    @Autowired
    private FxPopGDPDataImport fxPopGDPDataImport;

    @Override
    public JSONObject queryFxPopGDPs(FxPopGDPQueryParams queryParams, int curPage, int pageSize, String userId) {
        Page<FxPopGDPEntity> fxPopGDPPage = this.fxPopGDPNativeRepository.queryFxPopGDPs(queryParams, curPage, pageSize, userId);
        JSONObject jsonObject = PlatformPageUtils.formatPageData(fxPopGDPPage);
        return jsonObject;
    }

    @Override
    public String importShapeFile(String filePath, FxPopGDPQueryParams queryParams, String userId) {

        String province = queryParams.getProvince(), city = queryParams.getCity(), area = queryParams.getArea();

        String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length() - 4);

        StringBuilder returnMsg = new StringBuilder();

        List<FxPopGDPVO> pgVOs = new ArrayList<FxPopGDPVO>();
        List<List<Object>> list = VectorDataUtil.readSHPFile(filePath, "UTF-8");
        if (VectorDataUtil.judgeIsHaveMsssyCode(list) != -1) {
            list = VectorDataUtil.readSHPFile(filePath, "GBK");
            int msssyIndex = VectorDataUtil.judgeIsHaveMsssyCode(list);
            if (msssyIndex != -1)  return "messyCode#" + msssyIndex;
        }
        String judgeResult = judgeFieldParams(list);
        if (!("".equals(judgeResult))) return judgeResult + "上传数据失败, 请检查数据正确性!";


        String coordinate = "";
        double shapeLeng = 0.0, shapeArea = 0.0, lsGDP = 0.0, lsPop = 0.0;
        for (int i = 0; i < list.size(); i++) {
            List<Object> values = list.get(i);
            String wkt = values.get(0).toString();
            wkt = wkt.substring(wkt.indexOf("(") + 3, wkt.lastIndexOf(")))"));
            coordinate += "(" + wkt + "), ";
            if (!PlatformObjectUtils.isEmpty(values.get(2)) && !values.get(2).equals("")) {
                shapeLeng += Double.parseDouble(values.get(2).toString());
            }
            if (!PlatformObjectUtils.isEmpty(values.get(3)) && !values.get(3).equals("")) {
                shapeArea += Double.parseDouble(values.get(3).toString());
            }
            lsGDP += Double.parseDouble(values.get(4).toString());
            if (!PlatformObjectUtils.isEmpty(values.get(5)) && !values.get(5).equals("")) {
                lsPop += Double.parseDouble(values.get(5).toString());
            }
        }
        if ("0".equals(queryParams.getGdpUnit())) {//元

        } else if ("1".equals(queryParams.getGdpUnit())) {//万元
            lsGDP *= 10000;
        }
        if ("0".equals(queryParams.getPopUnit())) {//人

        } else if ("1".equals(queryParams.getPopUnit())) {//万人
            lsPop *= 10000;
        }
        coordinate = "MULTIPOLYGON ((" + coordinate.substring(0, coordinate.length() - 1) + "))";

        FxPopGDPVO pgVO = new FxPopGDPVO();
        pgVO.setProvince(province);
        pgVO.setCity(city);
        pgVO.setArea(area);
        pgVO.setAffiliatedFileName(fileName);
        pgVO.setCoordinate(coordinate);
        pgVO.setShape_Leng(String.valueOf(shapeLeng));
        pgVO.setShape_Area(String.valueOf(shapeArea));
        pgVO.setLs_GDP(String.format("%.2f", lsGDP));
        pgVO.setLs_Pop(String.valueOf((int) lsPop));

        pgVOs.add(pgVO);
        try {
            this.deleteFxPopGDPs(queryParams, userId);
            this.saveData(pgVOs, userId);
            returnMsg.append("成功导入" + pgVOs.size() + "条数据.");
            return returnMsg.toString();
        } catch (RuntimeException e) {
            e.printStackTrace();
            return "插入或更新数据出现错误: <br/>" + e.getMessage();
        } catch (Exception e) {
            e.printStackTrace();
            return "数据导入失败, 服务器内部出现异常!";
        }

    }

    private void saveData(List<FxPopGDPVO> list, String userId) throws Exception {
        List<FxPopGDPEntity> pgEntities = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            FxPopGDPEntity scrEntity = new FxPopGDPEntity();
            FxPopGDPVO pgVO = list.get(i);
            // 将VO数据映射拷贝到库表中
            BeanUtils.copyProperties(pgVO, scrEntity);
            scrEntity.setIsValid("1");
            scrEntity.setExtend3("CGCS2000");
            pgEntities.add(scrEntity);
        }
        fxPopGDPDataImport.sqlBatchSaveEntities(pgEntities, userId);
    }

    private String judgeFieldParams(List<List<Object>> list) {
        String str = "";
        for (int i = 0; i < list.size(); i++) {
            List<Object> values = list.get(i);
            if ("".equals(values.get(4))) {
                str += "第 " + i + " 条数据第 " + 4 + " 个字段数据为空.<br/>";
            }
        }
        return str;
    }


    public void deleteFxPopGDPs(FxPopGDPQueryParams queryParams, String userId) throws Exception {
        List<FxPopGDPEntity> fxPopGDPs = this.fxPopGDPNativeRepository.getFxPopGDPs(queryParams, userId);
        if (fxPopGDPs.size() > 0) fxPopGDPDataImport.sqlBatchDeleteEntities(fxPopGDPs);
    }

    public List<FxPopGDPEntity> getFxPopGDPs(FxPopGDPQueryParams queryParams, String userId) {
        List<FxPopGDPEntity> fxPopGDPs = this.fxPopGDPNativeRepository.getFxPopGDPs(queryParams, userId);
        return fxPopGDPs;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteFxPopGDPs(List<String> ids) {
        List<FxPopGDPEntity> fxPopGDPList = this.fxPopGDPRepository.findAllById(ids);
        if (!PlatformObjectUtils.isEmpty(fxPopGDPList) && fxPopGDPList.size() > 0) {
            for (FxPopGDPEntity fxPopGDPs : fxPopGDPList) {
                this.fxPopGDPRepository.delete(fxPopGDPs);
            }
        }
    }

}
